<template>
  <div class="upload-center-wrapper">
    <div class="upload-card">
      <!-- 文件选择按钮 -->
      <input
        type="file"
        ref="fileInput"
        @change="handleFileChange"
        style="display: none"
        accept=".mp3,.wav,.ogg"
      />
      <div class="center-row">
        <button
          @click="triggerFileSelect"
          class="upload-button"
          :class="{ 'disabled-button': isUploading }"
          :disabled="isUploading"
        >
          <template v-if="isUploading">
            已等待：{{ uploadElapsed }} 秒
          </template>
          <template v-else-if="analysisResult && uploadElapsed > 0">
            总用时：{{ uploadElapsed }} 秒
          </template>
          <template v-else>
            选择音频文件
          </template>
        </button>
      </div>

      <!-- 文件信息 -->
      <div v-if="selectedFile" class="file-info-card center-row">
        <svg class="file-icon" viewBox="0 0 24 24">
          <path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M13.5,16V14H11V16H8L12,20L16,16H13.5M13,9V3.5L18.5,9H13Z"/>
        </svg>
        <div class="file-details">
          <div class="file-name" :title="selectedFile.name">{{ truncatedName }}</div>
          <div class="file-meta">
            <span>{{ formatFileSize(selectedFile.size) }}</span>
            <span class="file-type">{{ selectedFile.type || '未知格式' }}</span>
          </div>
        </div>
        <button @click="resetSelection" class="reset-button" title="重新选择">×</button>
      </div>

      <!-- 上传控制 -->
      <div v-if="selectedFile" class="center-row">
        <button
          @click="submitFile"
          :disabled="isUploading"
          class="submit-button"
          :class="{ loading: isUploading }"
        >
          <template v-if="!isUploading">开始分析</template>
          <template v-else>
            <svg class="spinner" viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="20" fill="none" stroke="#fff" stroke-width="5" stroke-linecap="round" stroke-dasharray="90 150"/>
            </svg>
            <span>分析中...</span>
          </template>
        </button>
      </div>



      <!-- 分析结果 -->
      <div v-if="analysisResult" class="result-container">
        <div class="result-header center-row">
          <h3>识别结果</h3>
        </div>
        <div class="result-details-pair">
          <div class="detail-block">
            <div class="detail-label">原文</div>
            <div class="detail-value scrollable-text">{{ analysisResult.details[0].value }}</div>
          </div>
          <div class="detail-block">
            <div class="detail-label">翻译</div>
            <div class="translated-value scrollable-text">{{ translatedText || '（请点击翻译）' }}</div>
          </div>
        </div>
        <!-- 目标语言选择 -->
        <div class="center-row" style="margin-top: 1rem;">
          <label style="margin-right: 0.5rem; color: #64748b;">目标语言：</label>
          <select v-model="targetLang" style="padding: 0.3rem 1rem; border-radius: 6px; border: 1px solid #e2e8f0;">
            <option v-for="opt in langOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
          </select>
        </div>
        <div class="center-row" style="margin-top: 1rem;">
          <button
            class="translate-button"
            :disabled="isTranslating"
            @click="translateResult"
          >
            <span v-if="!isTranslating">翻译</span>
            <span v-else>翻译中...</span>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import axios from 'axios'

// 支持的目标语言列表
const langOptions = [
  { label: '英文', value: 'en' },
  { label: '中文', value: 'zh' },
  { label: '日文', value: 'jp' },
  { label: '韩文', value: 'kor' },
  { label: '法文', value: 'fra' },
  { label: '德文', value: 'de' },
  { label: '西班牙文', value: 'spa' },
]
const targetLang = ref('en')

const selectedFile = ref(null)
const isUploading = ref(false)
const statusMessage = ref('')
const statusType = ref('info')
const analysisResult = ref(null)
const translatedText = ref('')
const isTranslating = ref(false)
const MAX_FILE_SIZE = 50 * 1024 * 1024
const fileInput = ref(null)
const waitingSeconds = ref(3)
let waitingTimer = null
const uploadElapsed = ref(0)
let uploadTimer = null

watch(isUploading, (val) => {
  if (val) {
    waitingSeconds.value = 3
    waitingTimer = setInterval(() => {
      if (waitingSeconds.value > 0) {
        waitingSeconds.value--
      }
    }, 1000)
  } else {
    clearInterval(waitingTimer)
    waitingTimer = null
    waitingSeconds.value = 3
  }
})

const truncatedName = computed(() => {
  if (!selectedFile.value) return ''
  return selectedFile.value.name.length > 25
    ? selectedFile.value.name.substring(0, 22) + '...'
    : selectedFile.value.name
})

function triggerFileSelect() {
  if (!isUploading.value) fileInput.value.click()
}

function handleFileChange(e) {
  const file = e.target.files[0]
  if (!file) return
  const validTypes = ['audio/mpeg', 'audio/wav', 'audio/ogg']
  if (!validTypes.includes(file.type)) {
    showStatus('仅支持 MP3/WAV/OGG 格式', 'error')
    return
  }
  if (file.size > MAX_FILE_SIZE) {
    showStatus('文件大小不能超过50MB', 'error')
    return
  }
  selectedFile.value = file
  statusMessage.value = ''
  analysisResult.value = null
  translatedText.value = ''
}

function startUploadTimer() {
  uploadElapsed.value = 0
  clearInterval(uploadTimer)
  uploadTimer = setInterval(() => {
    uploadElapsed.value++
  }, 1000)
}
function stopUploadTimer() {
  clearInterval(uploadTimer)
  uploadTimer = null
}

async function submitFile() {
  if (!selectedFile.value || isUploading.value) return
  startUploadTimer()
  const formData = new FormData()
  formData.append('file', selectedFile.value)
  try {
    isUploading.value = true
    showStatus('正在上传和分析音频...', 'info')
    const res = await axios.post('http://localhost:8000/recognize', formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    })
    analysisResult.value = {
      waveform: Array(20).fill().map(() => Math.random() * 0.8 + 0.2),
      details: [{ label: '识别结果', value: res.data.text || '暂无文本' }]
    }
    showStatus('分析完成！', 'success')
    translatedText.value = ''
  } catch (err) {
    showStatus(err.response?.data?.message || '上传失败', 'error')
  } finally {
    isUploading.value = false
    stopUploadTimer()
  }
}

function resetSelection() {
  selectedFile.value = null
  statusMessage.value = ''
  analysisResult.value = null
  translatedText.value = ''
  fileInput.value.value = ''
  stopUploadTimer()
  uploadElapsed.value = 0
}

function formatFileSize(bytes) {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

function showStatus(msg, type = 'info') {
  statusMessage.value = msg
  statusType.value = type
  if (type !== 'error') setTimeout(() => (statusMessage.value = ''), 5000)
}

// 简单中英互译（可替换为真实API）
async function translateResult() {
  if (!analysisResult.value || !analysisResult.value.details[0].value) return
  isTranslating.value = true
  const text = analysisResult.value.details[0].value
  try {
    const res = await axios.post('http://localhost:8000/translate', { text, to_lang: targetLang.value })
    translatedText.value = res.data.translated + `（${targetLang.value}）`
  } catch (e) {
    translatedText.value = '翻译失败'
  } finally {
    isTranslating.value = false
  }
}
</script>

<style scoped>
.upload-center-wrapper {
  min-height: calc(100vh - 100px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  background: #f3f4f6;
  padding: 2rem 1rem 2rem 1rem;
  overflow-y: auto;
}
.upload-card {
  width: 100%;
  max-width: 720px;
  background: #fff;
  border-radius: 18px;
  box-shadow: 0 4px 24px 0 rgba(0,0,0,0.08);
  padding: 2.2rem 2.5rem 1.2rem 2.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  align-items: center;
  margin-bottom: 0;
}
.center-row {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1rem;
}
.upload-button,
.submit-button,
.reset-button,
.translate-button {
  transition: all 0.3s ease;
  cursor: pointer;
  border: none;
  border-radius: 8px;
  font-weight: 500;
}
.upload-button {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  background: #4361ee;
  color: #fff;
  font-size: 1rem;
}
.upload-button:hover:not(:disabled) {
  background: #3a56d4;
}
.disabled-button {
  background: #f0f2f5;
  color: #a8aeb8;
  cursor: not-allowed;
}
.file-info-card {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  width: 100%;
}
.file-icon { width: 40px; height: 40px; fill: #4361ee; }
.file-name { font-weight: 500; color: #1e293b; }
.file-meta { font-size: 0.875rem; color: #64748b; }
.reset-button {
  width: 32px; height: 32px;
  background: #fee2e2; color: #dc2626;
  font-size: 1.2rem; line-height: 1;
}
.reset-button:hover { background: #fecaca; }
.submit-button {
  padding: 12px 32px;
  background: #22c55e;
  color: white;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 120px;
  min-height: 40px;
  position: relative;
  gap: 6px;
}
.submit-button .spinner {
  width: 18px;
  height: 18px;
  margin-right: 6px;
  animation: spin 1s linear infinite;
  vertical-align: middle;
}
@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
.loading-dots {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 24px;
  gap: 4px;
}
.loading-dots span {
  display: block;
  width: 8px;
  height: 8px;
  background: #fff;
  border-radius: 50%;
  animation: bounce 1.2s infinite both;
}
.loading-dots span:nth-child(2) { animation-delay: 0.2s; }
.loading-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes bounce {
  0%, 80%, 100% { transform: scale(0.8); }
  40% { transform: scale(1.3); }
}
.translate-button {
  padding: 10px 28px;
  background: #f59e42;
  color: #fff;
  font-size: 1rem;
  margin-top: 0.5rem;
}
.translate-button:disabled {
  background: #fde68a;
  color: #b45309;
  cursor: not-allowed;
}
.status-message {
  padding: 1rem;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  justify-content: center;
}
.status-message.success { background: #dcfce7; color: #166534; }
.status-message.error   { background: #fee2e2; color: #b91c1c; }
.status-message.info    { background: #e0f2fe; color: #0369a1; }
.result-container {
  width: 100%;
  padding: 2.5rem 2rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.result-header h3 { margin: 0 0 1rem; color: #1e293b; }
.result-content, .waveform-preview, .waveform-bar { display: none !important; }
.result-details-pair {
  display: flex;
  flex-direction: row;
  gap: 3rem;
  width: 100%;
  justify-content: center;
  margin-top: 0.5rem;
}
.detail-block {
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  padding: 1.2rem 1.5rem;
  min-width: 260px;
  max-width: 480px;
  font-size: 1.08rem;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-start;
}
.detail-item {
  display: flex;
  justify-content: space-between;
  padding: 0.75rem;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  margin-bottom: 0.5rem;
}
.detail-label { color: #64748b; font-weight: 500; }
.detail-value, .translated-value { color: #1e293b; font-family: monospace; word-break: break-all; }
.translated-value { color: #2563eb; font-weight: 500; }
.translate-result {
  margin-top: 0.5rem;
  background: #f3f4f6;
  border-radius: 8px;
  padding: 0.75rem 1rem;
  font-size: 1rem;
  color: #1e293b;
  width: 100%;
  justify-content: flex-start;
  gap: 0.5rem;
}
.translated-value {
  color: #2563eb;
  font-weight: 500;
}
.slide-fade-enter-active, .slide-fade-leave-active {
  transition: all 0.3s ease-out;
}
.slide-fade-enter-from, .slide-fade-leave-to {
  transform: translateY(-10px); opacity: 0;
}
.waiting-timer {
  color: #fff;
  font-weight: 500;
  margin-left: 6px;
  letter-spacing: 1px;
  font-size: 1rem;
}
.scrollable-text {
  max-height: 240px;
  overflow-y: auto;
  word-break: break-all;
  padding-right: 4px;
}
@media (max-width: 900px) {
  .upload-card {
    max-width: 99vw;
    padding: 1.2rem 0.5rem;
  }
  .result-details-pair {
    flex-direction: column;
    gap: 1rem;
    align-items: stretch;
  }
  .detail-block {
    min-width: auto;
    max-width: none;
  }
}

@media (max-width: 768px) {
  .upload-center-wrapper {
    padding: 1rem 0.5rem;
  }
  .upload-card {
    padding: 1rem;
  }
  .result-container {
    padding: 1.5rem 1rem;
  }
  .scrollable-text {
    max-height: 180px;
  }
}

@media (max-height: 600px) {
  .upload-center-wrapper {
    padding: 1rem 0.5rem;
  }
  .upload-card {
    padding: 1rem;
    gap: 1rem;
  }
  .result-container {
    padding: 1rem;
  }
  .scrollable-text {
    max-height: 120px;
  }
}
</style>